package com.ms.education.acl.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ms.education.acl.entity.Permission;
import com.ms.education.acl.entity.RolePermission;
import com.ms.education.acl.helper.MemuHelper;
import com.ms.education.acl.helper.PermissionHelper;
import com.ms.education.acl.mapper.PermissionMapper;
import com.ms.education.acl.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ms.education.acl.service.RolePermissionService;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author ms
 * @since 2023-02-18
 */
@Service
public class PermissionServiceImp extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;

    @Override
    public List<Permission> queryAllPermission() {
        List<Permission> permissions = list();
        //筛选出所有一级菜单
        List<Permission> firstLevelPer = permissions.stream().filter(p -> p.getPid() == 0).peek(p -> p.setLevel(1)).collect(Collectors.toList());
        firstLevelPer.forEach(p -> findPerChildren(permissions, p));
        return firstLevelPer;
    }

    public static void findPerChildren(List<Permission> permissions, Permission parPermission) {
        List<Permission> children = new LinkedList<>();
        permissions.forEach(p -> {
            if (p.getPid() == parPermission.getId()) {
                p.setLevel(parPermission.getLevel() + 1);
                children.add(p);
                findPerChildren(permissions, p);
            }
        });
        parPermission.setChildren(children);
    }

    @Override
    public void remove(Integer id) {
        List<Permission> permissions = list();
        Set<Integer> deleteIds = new HashSet<>();
        deleteIds.add(id);
        permissions.forEach(p -> {
            if (deleteIds.contains(p.getPid())) {
                deleteIds.add(p.getId());
            }
        });
        removeBatchByIds(deleteIds);
    }

    //@Transactional
    @Override
    public void doAssign(Integer roleId, Integer[] permissionIds) {
        LinkedList<RolePermission> rolePermissions = new LinkedList<>();
        for (Integer permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissions.add(rolePermission);
        }
        UpdateWrapper<RolePermission> wrapper = new UpdateWrapper<RolePermission>().eq("role_id", roleId);
        rolePermissionService.remove(wrapper);
        rolePermissionService.saveBatch(rolePermissions);
    }


    @Override
    public List<Permission> toAssign(Integer roleId) {
        //获取角色对应的权限id
        Set<Integer> permissionIds = rolePermissionService
                .list(new QueryWrapper<RolePermission>()
                        .eq("role_id", roleId)
                        .select("permission_id"))
                .stream()
                .map(RolePermission::getPermissionId).collect(Collectors.toSet());
        List<Permission> permissions = list(new QueryWrapper<Permission>().orderByAsc("id"));
        permissions.forEach(permission -> {
            if (permissionIds.contains(permission.getId())) {
                permission.setSelect(true);
            }
        });

        List<Permission> firstLevelPer = permissions.stream().filter(p -> p.getPid() == 0).peek(p -> p.setLevel(1)).collect(Collectors.toList());
        firstLevelPer.forEach(p -> findPerChildren(permissions, p));
        return firstLevelPer;


    }

    @Override
    public List<String> permissionValueList(Integer userId) {
        return baseMapper.permissionValueList(userId);
    }

    @Override
    public List<JSONObject> getMenu(Integer userId) {
        List<Permission> permissions=baseMapper.getUserMenu(userId);
        return MemuHelper.bulid(PermissionHelper.bulid(permissions));
    }
}
